﻿using Service.Domain.Shared.Models;
using Service.Domain.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Service.Domain.Interfaces;
using Service.Application.Interface;
using Service.Domain.Interfaces.DomainService;
using Service.Infrastructure.Interfaces;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using Service.Domain.Entities.User;
using Service.Domain.Interfaces.Factories;

namespace Service.Application.AccountService
{
    public class AccountAppService : IAccountAppService
    {
        readonly IUserService userService;
        readonly IConfiguration Configuration;
        readonly IHttpContextAccessor Accessor;
        readonly IUserFactory userFactory;
        readonly ICacheManager cacheManager;

        public AccountAppService(IUserService userService, ICacheManager cacheManager, IConfiguration configuration, IHttpContextAccessor accessor, IUserFactory userFactory)
        {
            this.userService = userService;
            this.Configuration = configuration;
            this.Accessor = accessor;
            this.userFactory = userFactory;
            this.cacheManager = cacheManager;
        }

        public async Task<User> Login(LoginDto user)
        {
            var userDomain = this.userFactory.CreateRoot();

            await userDomain.Login(user.UserName, user.Password);

            await userDomain.GetRoles();

            await userDomain.GetPermissionsAsync();

            var jwtConfig = Configuration.GetSection("Jwt");

            var securityKey = new SigningCredentials(new SymmetricSecurityKey(Encoding.ASCII.GetBytes(jwtConfig.GetSection("Secret").Value)), SecurityAlgorithms.HmacSha256);

            var claims = new Claim[] {
                new Claim(JwtRegisteredClaimNames.Iss, jwtConfig.GetSection("Iss").Value),
                new Claim(JwtRegisteredClaimNames.Aud, jwtConfig.GetSection("Aud").Value),
                new Claim(ClaimTypes.NameIdentifier, userDomain.Root.Id.ToString()),
                new Claim("Guid",Guid.NewGuid().ToString("D")),
                new Claim(ClaimTypes.Role,"system"),
                new Claim(ClaimTypes.Role,"admin"),
            };
            SecurityToken securityToken = new JwtSecurityToken(
                signingCredentials: securityKey,
                expires: DateTime.Now.AddMinutes(30),//过期时间
                claims: claims
            );

            var token = new JwtSecurityTokenHandler().WriteToken(securityToken);


            // 2.将用户数据和权限保存起来
            await cacheManager.PutAsync($"Permission_{userDomain.Root.Id}", userDomain.Permissions);
            await cacheManager.PutAsync($"User_{userDomain.Root.Id}", userDomain.Root);

            return userDomain;
        }

        public UserInfo GetLoginUser()
        {
            UserInfo model = null;

            var identity = (ClaimsIdentity)this.Accessor.HttpContext.User.Identity;
            var claim = identity.Claims.FirstOrDefault(q => q.Type == ClaimTypes.NameIdentifier);
            if (int.TryParse(claim.Value, out int userId))
            {
                
            }


            return model;
        }
    }
}
